package main

import (
	"flamego-study/dao"
	"flamego-study/model"
	"net/http"
	"net/url"
	"os"
	"runtime"
	"time"
	"unicode"

	"github.com/charmbracelet/log"
	"github.com/flamego/binding"
	"github.com/flamego/flamego"
	"go.uber.org/zap"
)

func main() {

	dao.Init()
	development, err2 := zap.NewDevelopment()
	if err2 != nil {
		println(err2)
	}
	logger := development.Sugar()
	flamego.SetEnv(flamego.EnvTypeDev)
	f := flamego.Classic()

	// json处理中间件
	f.Use(flamego.Renderer(
		flamego.RenderOptions{
			JSONIndent: "  ", // Indent：缩进
		},
	))

	f.Get("/", func() string {
		logger.Info("首页访问中")
		return "Hello, Flamego!"
	})

	f.Get("/json", func(c flamego.Context, r flamego.Render) {
		responseMap := make(map[string]interface{})
		status := http.StatusOK
		responseMap["status"] = status
		responseMap["message"] = http.StatusText(status)
		r.JSON(http.StatusOK, responseMap)
	})

	f.Get("/download", func(c flamego.Context) {

		des := "/home/eric/Project/Go/go-cqhttp/modules/pprof/pprof.go"
		filename := "pprof.go"
		writer := c.ResponseWriter()

		fileData, err := os.ReadFile(des)
		if err != nil {
			logger.Errorf("Read File Err: %v", err.Error())
		} else {
			if isASCII(filename) {
				writer.Header().Set("Content-Disposition", `attachment; filename="`+filename+`"`)
			} else {
				writer.Header().Set("Content-Disposition", `attachment; filename*=UTF-8''`+url.QueryEscape(filename))
			}
			writer.Write(fileData)
		}
	})
	// 构建一个通道
	ch := make(chan int64)
	f.Get("/time", func(c flamego.Context, r flamego.Render) {

		// 开启一个并发匿名函数
		go func() {
			data := time.Now().UTC().Unix()
			ch <- data

		}()

		r.JSON(http.StatusOK, "3秒后打印时间到了")

	})

	// 组合
	f.Group("/api", func() {
		f.Any("/version", func(c flamego.Context, r flamego.Render) {
			data := make(map[string]any)
			version1 := runtime.Version()
			data["go-version"] = version1
			r.JSON(http.StatusOK, data)
		})

		f.Group("/user", func() {
			f.Get("/list", func(c flamego.Context, r flamego.Render) {

				r.JSON(http.StatusOK, dao.UserDao.ListAll())
			})

			// 解决参数映射问题 https://github.com/flamego/binding/
			f.Post("/", binding.JSON(model.UserModel{}), func(c flamego.Context, user model.UserModel, r flamego.Render) {
				log.Infof("当前请求body %+v", user)
				dao.UserDao.Save(user)
				r.JSON(http.StatusOK, user)
			})

			f.Delete("/", binding.JSON(model.UserModel{}), func(c flamego.Context, user model.UserModel, r flamego.Render) {
				log.Infof("删除：当前请求body %+v", user)
				affect := dao.UserDao.Delete(user)
				r.JSON(http.StatusOK, affect)

			})

			f.Put("/", binding.JSON(model.UserModel{}), func(c flamego.Context, user model.UserModel, r flamego.Render) {
				log.Infof("更新：当前请求body %+v", user)
				affect := dao.UserDao.Update(user)
				r.JSON(http.StatusOK, affect)
			})

		})

	})

	//新开一个协程
	myTimer := time.NewTimer(time.Second * 3) // 启动定时器

	go func() {
		for {
			select {
			case num := <-ch:
				logger.Info("num = ", zap.Int64("attempt", num))
				myTimer.Reset(time.Second * 3)
			case <-myTimer.C:
				logger.Info("初始化跑一次，3秒钟时间到了")
			}
		}
	}() //别忘了()

	logger.Info("Server is running...")
	f.Run()

}

func isASCII(s string) bool {
	for i := 0; i < len(s); i++ {
		if s[i] > unicode.MaxASCII {
			return false
		}
	}
	return true
}
